// 立即执行函数 避免污染window环境

//function函数的this指向:函数的方式调用this指向window、实例化对象调用时谁调用this就指向谁(可以使用call，apply，bind等方法来改变this的指向)
//箭头函数的this指向：取决当前函数所声明的位置的this指向(外层函数中的this指向)

(function (window) {
    function Promise(executor) { // 构造函数 Promise
        // 给Promise构造函数中添加两个属性
        this.PromiseState = 'pending'
        this.PromiseResult = 'undefined'

        //包装成功的函数
        let resolve = (value) => {
            if (this.PromiseState!=='pending') return
            this.PromiseResult = value
            this.PromiseState = 'fulfilled'
        }
        // 包装失败的函数
        let reject = reason => {
            if (this.PromiseState!=='pending') return
            this.PromiseState = 'rejected'
            this.PromiseResult = reason
        }

        //
        try {
            executor(resolve, reject)
        } catch (e) {   // 当抛出错误时执行 catch 回调函数
            this.PromiseState = 'rejected'
            this.PromiseResult = e
        }

    }

    //then方法
    //借助于Object.assign方法进行对象合并 Object.assign(target,...sources) target -- 目标对象(将后面的对象合并到这里面)、source -- 源对象
    Object.assign(Promise.prototype,{

        // ES6 中的简便写法  onFulfilled--成功的回调函数 onRejected--失败的回调函数
        then(onFulfilled,onRejected){
            if (this.PromiseState==='fulfilled'){
                // 让成功的回调函数慢于同步执行代码，需要调用计时器即可
                //异步调用
                setTimeout(()=>{
                    onFulfilled(this.PromiseResult)
                })
            }else if (this.PromiseState==='rejected'){
                setTimeout(()=>{
                    onRejected(this.PromiseResult)
                })
            }else {
                setTimeout(()=>{
                    console.log('undefined')
                })
            }
        }
    })

    //暴漏
    window.Promise = Promise
})(window)